import { TYPES, downloadFile, countTextLength, base64ToPathFn } from './util'
/**
 * 参数类
 */
export default class Params {
	
	/**
	 * 获取图片src路径
	 * @param { String } src 图片地址
	 * @returns 
	 */
	getImageSrc(src) {
		return new Promise(async resolve => {
			src = await base64ToPathFn(src)
			// #ifndef MP-TOUTIAO
			if (src.includes('http')) {
				const downlaod = await downloadFile(src)
				if (downlaod.data.statusCode != 200) {
					hideLoading()
					return resolve({
						success: false,
						msg: `图片路径为:${src}的文件下载失败`
					})
				}
				if (!downlaod.success) {
					hideLoading()
					return resolve({
						success: false,
						msg: '下载图片失败'
					})
				}
				src = downlaod.data.tempFilePath
			}
			// #endif
			return resolve({
				success: true,
				src
			})
		})
	}

	/**
	 * 获取绘制图片的内容
	 * @param { String } src 资源目录
	 */
	getImage(src) {
		const { type, canvas } = this
		if (TYPES.includes(type)) {
			const img = canvas.createImage()
			// const imageData = canvas.createImageData()
			img.src = src
			return img
		} else {
			return src
		}
	}

	/**
	 * 获取阴影参数
	 * @param { Boolean } shadow.show 是否使用阴影
	 * @param { Number } shadow.x 阴影相对于形状在水平方向的偏移
	 * @param { Number } shadow.y 阴影相对于形状在竖直方向的偏移
	 * @param { Number } shadow.blur 阴影的模糊级别，数值越大越模糊
	 * @param { String } shadow.color 阴影的颜色
	 * @returns 
	 */
	getShadow(shadow = {}) {
		const { show = false, x = 0, y = 0, blur = 0, color = '#000000' } = shadow
		return { show, x, y, blur, color }
	}

	/**
	 * 获取渐变参数
	 * @param { String } type 渐变类型 linear: 线性 circle: 圆形
	 * @param { Boolean } relative 相对定位
	 * @param { Object } position 位置
	 * @param { Object } colors 颜色
	 * @param { Object } box 盒子的位置
	 * @returns 
	 */
	getGradient(type = 'linear', relative = true, position = {}, colors = [], box = {}) {
		const { x0 = 0, y0 = 0, x1 = 0, y1 = 0, x = 0, y = 0, r = 0 } = position
		if (type == 'linear') {
			position.x0 = relative ? x0 + box.x : x0
			position.y0 = relative ? y0 + box.y : y0
			position.x1 = relative ? x1 + box.x : x1
			position.y1 = relative ? y1 + box.y : y1
		} else {
			position.x = relative ? x + box.x : x
			position.y = relative ? y + box.y : y
			position.r = r
		}
		return type == 'linear' ?  this.getLinearGradient(position, colors) : this.getCircularGradient(position, colors)
	}

	/**
	 * 获取线性渐变颜色
	 * @param { Object } position 位置对象
	 * @param { Array } colors 颜色坐标
	 */
	getLinearGradient(position = {}, colors = []) {
		const { Context } = this
		const { x0, y0, x1, y1 } = position
		const grd = Context.createLinearGradient(x0, y0, x1, y1)
		for(let i of colors) {
			grd.addColorStop(i.stop, i.color)
		}
		return grd
	}

	/**
	 * 获取圆形渐变
	 * @param { Object } position 位置对象
	 * @param { Array } colors 颜色坐标
	 */
	getCircularGradient(position = {}, colors = []) {
		const { Context } = this
		const { x, y, r } = position
		const grd = Context.createCircularGradient(x, y, r)
		for(let i of colors) {
			grd.addColorStop(i.stop, i.color)
		}
		return grd
	}

	/**
	 * 高亮文字
	 * @param { Array } textArr 绘制文字数组
	 * @param { Array } highlightText 高亮文字
	 * @param { String } color 字体原颜色
	 * @param { String } font 字体
	 * @returns 
	 */
	getHighlightText(textArr, highlightText, color, font) {
		const highlightTextArr = []
		const highlightColorArr = []
		const { fontSize } = font
		highlightText.map(item => {
			const { text, color } = item
			return [...text].map(i => { 
				return {
					text: i,
					color
				}
			})
		}).forEach(item => {
			const texts = item.map(item => item.text)
			const colors = item.map(item => item.color)
			highlightTextArr.push(...texts)
			highlightColorArr.push(...colors)
		})
		const rowData = []
		textArr.forEach((item, index) => {
			const { x, y, w, text, tx, ty, tw } = item
			const texts = [...text]
			let position = []
			for (let i in texts) {
				const data = texts[i]
				const current = highlightTextArr.findIndex(i => data == i)
				if (current != -1) {
					// 符合规则的内容
					const ruleData = {
						text: data,
						index: i,
						x: x + countTextLength(this.Context, texts.join('').substring(0, i), fontSize),
						fontColor: highlightColorArr[current],
						y,
						tx,
						ty,
						tw
					}
					const beforeIndex = position.length == 0 ? 0 : Number(position[position.length - 1].index)
					const currentIndex = Number(ruleData.index)
					if (currentIndex - beforeIndex > 1) {
						const other = {
							text: texts.join('').substring(position[beforeIndex] ? beforeIndex + 1 : beforeIndex, currentIndex),
							index: beforeIndex === 0 ? 0 : beforeIndex + 1,
							x: x + countTextLength(this.Context, texts.join('').substring(0, position[beforeIndex] ? beforeIndex + 1 : beforeIndex), fontSize),
							fontColor: color,
							y,
							tx,
							ty,
							tw
						}
						rowData.push(other)
					}
					position.push(ruleData)
					rowData.push(ruleData)
				}
			}
			if (position.length === 0) {
				rowData.push({
					...item,
					tx,
					ty,
					tw,
					fontColor: color
				})
			}
			if (position.length != 0) {
				const lastIndex = Number(position[position.length - 1].index) + 1
				const length = texts.length
				if (lastIndex == length) return
				const other = {
					text: texts.join('').substring(lastIndex, length),
					index: lastIndex,
					x: x + countTextLength(this.Context, texts.join('').substring(0, lastIndex), fontSize),
					fontColor: color,
					y,
					tx,
					ty,
					tw
				}
				rowData.push(other)
			}
		})
		return rowData
	}

	/**
	 * 获取字体样式
	 * @param { Object } font 字体
	 * @param { Object } conversion 是否转换单位默认true
	 */
	getFont(font = {}, conversion = true) {
		const { size = this.type === 'default' ? 16 : 32, family = 'sans-serif', style = 'normal', variant = 'normal', weight = 'normal' } = font
		return {
			fontSize: size,
			fontSizeBefore: size,
			fontFamily: family,
			fontStyle: style,
			fontVariant: variant,
			fontWeight: weight,
			style: `${style} ${variant} ${weight} ${conversion ? this.getUnit(size) : size}px ${family}`
		}
	}

	/**
	 * 获取文字line样式
	 * @param { Object } line 行高
	 * @param { Object } conversion 是否转换单位默认true
	 */
	getTextLine(line = {}, conversion = true) {
		const { num = -1, height = 0, style = 'none', type = 'solid', width = 1 } = line
		return {
			lineNum: num,
			lineHeight: conversion ? this.getUnit(height) : height,
			lineStyle: style,
			lineType: type, 
			lineWidth: width
		}
	}
}